/*
 ============================================================================
 Name		: PosReader.cpp
 Author	  : Den Grigorenko
 Copyright   : Copyright (c) 2008 Den123
 Description : CPositionReader implementation
 ============================================================================
 */

#include "PosReader.h"


CPositionReader :: CPositionReader():
   CActive( CActive :: EPriorityStandard )
{
   CActiveScheduler :: Add( this );
}

void CPositionReader :: ConstructL()
{
   User :: LeaveIfError( iServer.Connect() );
   User :: LeaveIfError( iPositioner.Open( iServer ) );

   // register requestor		
   _LIT( KAppName, "CelestialSphere_0xEEC98BE4" );
   User::LeaveIfError(iPositioner.SetRequestor(
        CRequestor::ERequestorService,
        CRequestor::EFormatApplication,
        KAppName ) );
	
   // Set maximum allowed time for a location request
   const TInt K30Seconds = 30000000;
   TTimeIntervalMicroSeconds timeOut( K30Seconds );
   TPositionUpdateOptions updateOptions;
   updateOptions.SetUpdateTimeOut( timeOut );
   User::LeaveIfError( iPositioner.SetUpdateOptions( updateOptions ) );    
}


// requests
void CPositionReader :: ReadPosInfo()
{
   ReadInternal( iPositionInfo );
}
void CPositionReader :: ReadCourseInfo()
{
   ReadInternal( iPositionCourseInfo );
}
void CPositionReader :: ReadSatelliteInfo()
{
   ReadInternal( iPositionSatelliteInfo );
}


// data access
TPositionInfo& CPositionReader :: PosInfo()
{
   return iPositionInfo;
}
const TPositionCourseInfo& CPositionReader :: CourseInfo()
{
   return iPositionCourseInfo;
}
const TPositionSatelliteInfo& CPositionReader :: SatelliteInfo() 
{
   return iPositionSatelliteInfo;
}

// factory
CPositionReader* CPositionReader :: NewL( MPositionReaderObserver* anObserver )
{
   CPositionReader* self = new (ELeave) CPositionReader();
   CleanupStack :: PushL( self );
   self->ConstructL();
   self->iObserver = anObserver;
   CleanupStack :: Pop( self );	
   return self;
}

// destructor
CPositionReader :: ~CPositionReader()
{
   Cancel();
   iPositioner.Close();
   iServer.Close();	
}

// async rq issuing
void CPositionReader :: ReadInternal( TPositionInfoBase& anInfo )
{
   iCurInfo = &anInfo;
   Cancel();
   iStatus = KRequestPending;	
   iPositioner.NotifyPositionUpdate( anInfo, iStatus );
   SetActive();
}

// request completed
void CPositionReader :: RunL()
{
   if( iStatus == KErrNone )
   {
      // Location retrieved. Operation finished.
      iObserver->ReadingComplete( *iCurInfo );
   }
   else
      iObserver->ReadingError( iStatus.Int() );
}

void CPositionReader :: DoCancel()
{	
   iPositioner.CancelRequest( EPositionerNotifyPositionUpdate );	
}
